package com.lx.boot.web.convert.deserializer;

import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
import com.lx.boot.web.convert.DFunction;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.lang.annotation.Annotation;
import java.util.Objects;

@Slf4j
public class DeserializeHandler extends JsonDeserializer<Object> implements ContextualDeserializer {

    private Annotation annotation;

    private Class filedType;

    private DFunction<DeserializerPara, Annotation, ? extends Object> function;


    @Override
    public Object deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
        return function.apply(new DeserializerPara(jsonParser,filedType),annotation);
    }


    @SneakyThrows
    @Override
    public JsonDeserializer<?> createContextual(DeserializationContext deserializationContext, BeanProperty property) throws JsonMappingException {
        if (filedType != null){
            return this;
        }
        filedType = property.getType().getRawClass();
        Deserialize deserialize = property.getAnnotation(Deserialize.class);
        if (Objects.nonNull(deserialize)) {
            this.annotation = property.getAnnotation(deserialize.value());
            if (this.annotation == null){
                this.annotation = deserialize;
            }
            this.function = (DFunction<DeserializerPara, Annotation, ? extends Object>) deserialize.function().getConstructor().newInstance();
            return this;
        }
        return deserializationContext.findContextualValueDeserializer(property.getType(), property);
    }

}
